<?php
/**
 * @author Artur Bier <izatop@gmail.com>
 * @package Db.Result.Iterator
 *
 * @copyright TinyWEB CMS
 * @link http://tinywebcms.ru
 * @link http://cms.vingrad.ru
 * @version SVN: $Id$ 
 */
 
/**
 * DbResultIterator
 */
class DbResultIterator extends Object implements Iterator
{
    /**
     * Текущий элемент выборки.
     * 
     * @var mixid
     */
    protected $current    = null;
    
    /**
     * Текущий индекс выборки.
     * 
     * @var int
     */
    protected $key        = 0;
    
    /**
     * Ресурс выборки.
     *
     * @var mysqli_result
     */
    private $result;

    /**
     * Конструктор. Получает указатель на результат выборки.
     *
     * @param mysqli_result $result
     */
    public function __construct($result)
    {
        $this->result   = $result;
    }
    
    /**
     * Текущий элемент выборки
     * 
     * @return mixed
     */
    public function current()
    {
        return $this->current;
    }
    
    /**
     * Текущая позиция указателя.
     * 
     * @return int
     */
    public function key()
    {
        if($this->key >= $this->count())
        {
            $this->rewind();
        }
        
        return $this->key;
    }
    
    /**
     * Сдвигает указатель в выборкеи возвращает данные.
     * 
     * @return array
     */
    public function next()
    {
        $this->key++;
        $this->current = $this->result->fetch_assoc();
        return $this->current;
    }
    
    /**
     * Сброс указателя результата к начальным значениям.
     * 
     */
    public function rewind()
    {
        $this->current = null;
        $this->key     = 0;
        
        if ($this->count()) {
            $this->seek(0);
            $this->current  = $this->result->fetch_assoc();
        }
        
        return $this->current;
    }
    
    /**
     * Проверка наличия результата
     * Пример:
     * <code>
     * while($result->valid()){
     *      print_r($result->next());
     * }
     * </code>
     * 
     * @return bool
     */
    public function valid()
    {
        if (!$this->count()) {
            return false;
        }
        
        return $this->key < $this->count();
    }
    
    /**
     * Перемещение указателя результата к указанной позиции.
     * 
     * @return bool
     */
    public function seek($offset = 0)
    {
        if($offset < $this->count()) {
            return $this->result->data_seek($offset);
        }
        
        return false;
    }
    
    /**
     * Возвращает количество записей выборки.
     *
     * @return int
     */
    public function count()
    {
        return $this->result->num_rows;
    }
    
    public function fetch($mode = MYSQLI_ASSOC)
    {
        return $this->result->fetch_array($mode);
    }
    
    /**
     * Экспорт данных выборки.
     *
     * @return array
     */
    public function export($key = null)
    {
        $rows   = array();
        if(isset($key))
        {
            foreach ($this as $row)
            {
                $rows[$row[$key]] = $row;
            }
        } 
        else 
        {
            foreach ($this as $row)
            {
                $rows[] = $row;
            }
        }

        return (array) $rows;
    }
    
    /**
     * Освобождаем ресурс результата выборки.
     * 
     * @return boolean
     */
    public function free()
    {
        $this->result->free_result();
    }
}

?>